#pragma once
#include <vector>
#include <string>

template<typename A>
inline void unserialize(std::vector<byte>::const_iterator& vit,
      const std::vector<byte>::const_iterator &end, A &a) {
   a.fromVec(vit, end);
}

template<>
inline void unserialize<int>(std::vector<byte>::const_iterator& vit, 
      const std::vector<byte>::const_iterator &end, int & ret) {
   ret = ntohl(*(int*)&*vit);
   vit += 4;
}

template<>
inline void unserialize<uint32_t>(std::vector<byte>::const_iterator& vit, 
     const std::vector<byte>::const_iterator &end, uint32_t & ret) {
   ret = ntohl(*(uint32_t*)&*vit);
   vit += 4;
}

template<>
inline void unserialize<short>(std::vector<byte>::const_iterator& vit,
     const std::vector<byte>::const_iterator &end, short & ret) {
   ret = ntohs(*(short*)&*vit);
   vit += 2;
}

template<>
inline void unserialize<unsigned short>(std::vector<byte>::const_iterator& vit,
     const std::vector<byte>::const_iterator &end, unsigned short & ret) {
   ret = ntohs(*(unsigned short*)&*vit);
   vit += 2;
}

template<>
inline void unserialize<bool>(std::vector<byte>::const_iterator& vit,
     const std::vector<byte>::const_iterator &end, bool & ret) {
   ret = *vit++;
}

template<>
inline void unserialize<std::string>(std::vector<byte>::const_iterator& vit,
      const std::vector<byte>::const_iterator &end, std::string &s) {
   int len; unserialize<int>(vit, end, len);

   // HACK: need to check vit+len
   s = std::string(vit, vit+len);
   vit += len;
}
